using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Xml;
using System.Diagnostics;

namespace FreeHTPC
{
	class MediaPlayerClassic
	{
		/// <summary>
		/// Special window to capture events from Media Player Classic
		/// </summary>
		private class innerWindow : Form
		{
			private MediaPlayerClassic mpc;
			public innerWindow(MediaPlayerClassic mpc)
				: base()
			{
				this.mpc = mpc;
				Text = "MediaPlayerClassic_API_Wrapper";
				Visible = false;
				Hide();
			}
			protected override void WndProc(ref Message m)
			{
				if (mpc.wndProc(ref m))
					base.WndProc(ref m);
			}
		}
			
		private IntPtr windowHandle = IntPtr.Zero;
		private innerWindow myWindow;
		private HandleRef handleRef;
		private IntPtr WindowHandle
		{
			get { return windowHandle; }
			set
			{
				windowHandle = value;
				handleRef = new HandleRef(this,windowHandle);
			}
		}


		private static void process_WM_COPYDATA(ref Message m, out string[] pairs, out MPCAPI_COMMAND command)
		{
			Win32API.COPYDATASTRUCT CD = (Win32API.COPYDATASTRUCT)m.GetLParam(typeof(Win32API.COPYDATASTRUCT));
			command = (MPCAPI_COMMAND)CD.dwData;
			byte[] B = new byte[CD.cbData];
			IntPtr lpData = CD.lpData;
			Marshal.Copy(lpData, B, 0, CD.cbData);
			string strData = Encoding.Unicode.GetString(B);
			strData = strData.Substring(0, strData.Length - 1);
			
			pairs = strData.Split('|');
		}

		private bool wndProc(ref Message m)
		{
			
			if(m.Msg == Win32API.WM_COPYDATA)
			{
				string[] pairs;
				MPCAPI_COMMAND command;
				process_WM_COPYDATA(ref m, out pairs, out command);
				switch(command)
				{
					case MPCAPI_COMMAND.CMD_CONNECT:
						WindowHandle = new IntPtr(long.Parse(pairs[0]));
						return false;
					case MPCAPI_COMMAND.CMD_STATE:
						return false;
					case MPCAPI_COMMAND.CMD_PLAYMODE:
						return false;
					case MPCAPI_COMMAND.CMD_NOWPLAYING:
						return false;
						
				}
				
			}		
			return true;
		}
		
		public MediaPlayerClassic()
		{
			myWindow = new innerWindow(this);
		}

		private const int MAX_STRING = 16 * 1024 * 1024;
		private StringBuilder lpString = new StringBuilder(MAX_STRING);
		private static IntPtr maxString = new IntPtr(MAX_STRING);
		
		
		private void ObtainText()
		{
			int len =  Win32API.SendMessage(handleRef, 1, maxString, lpString).ToInt32();
			string text = lpString.ToString().Substring(0, len - 1);
			XmlDocument doc = new XmlDocument();
			doc.LoadXml(text);
			// Let's parse xml here:
			
		}

		private string[] audioTracks;
		private string[] subtitles;
		private int currentAudioTrack;
		private int currentSubtitle;
		private int audioDelay;
		private int subtitleDelay;
		private string[] playlist;
		private int currentFile;
		private string[] chapters;
		private int currentChapter;
		
		private TimeSpan duration;
		private TimeSpan position;
		private Process mplayercProcess;

		public event EventHandler FileChanged;
		public event EventHandler StateChanged;
		
		private void killAllMplayerc()
		{
			Process[] mplayercProcesses = Process.GetProcessesByName("mplayerc");
			foreach (Process process in mplayercProcesses)
			{
				process.Kill();
				process.WaitForExit();
			}
		}
		
		
		public void StartProcess()
		{
			if(mplayercProcess==null || mplayercProcess.HasExited)
			{
				string executablePath = Application.StartupPath + "\\MPC\\mplayerc.exe";
				string arguments = "/SLAVE " + myWindow.Handle;
				//1 - let's find existing process
				Process[] mplayercProcesses = Process.GetProcessesByName("mplayerc");
				Process mplayercProcessLocal = null;
				bool startNew = true;
				if (mplayercProcesses.Length != 0)
				{
					mplayercProcessLocal = mplayercProcesses[0];
					if (mplayercProcessLocal.StartInfo.Arguments != arguments)
						mplayercProcessLocal.Kill();
					else
						startNew = false;
				}
				if (startNew)
				{
					killAllMplayerc();
					WindowHandle = IntPtr.Zero;
					mplayercProcessLocal = Process.Start(executablePath, arguments);
					while (WindowHandle == IntPtr.Zero)
					{
						Thread.Sleep(100);
						Application.DoEvents();
					}
				}
				mplayercProcess = mplayercProcessLocal;
			}
		}



		

		
		private int sendCommand(MPCAPI_COMMAND commandToSend)
		{
			return Win32API.SendMessage_WM_COPYDATA(handleRef, IntPtr.Zero, (int)commandToSend, null).ToInt32();
		}
		
		private int sendString(MPCAPI_COMMAND commandToSend, string stringToSend)
		{
			return Win32API.SendMessage_WM_COPYDATA(handleRef, IntPtr.Zero, (int) commandToSend, stringToSend, Encoding.Unicode).ToInt32();
		}
		
		public void CloseProcess()
		{
			
		}
		
		public void SetPlaylist(int index, params string [] files)
		{
			
			
		}
		
		public void SetPlaylistPosition(int index)
		{
			
		}
		
		public void Stop()
		{
			sendCommand(MPCAPI_COMMAND.CMD_STOP);
		}
		
		public void PlayPause()
		{
			sendCommand(MPCAPI_COMMAND.CMD_PLAYPAUSE);
		}

		public void OpenFile(string filePath)
		{
			sendString(MPCAPI_COMMAND.CMD_OPENFILE, filePath);
		}		
		
		
		
	}
}
